/*
 * Server.cpp
 *
 *  Created on: May 17, 2011
 *      Author: madboyka
 */

#include "Server.h"
#include "ClientListener.h"
#include "ViewerListener.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include "config.h"
#include "Logger.h"
#include <QStringList>
#include <QVariant>

Server *Server::instance;
Console *Server::console;
QSettings *Server::settings;

Server::Server()
{
	settings = new QSettings("settings.ini", QSettings::IniFormat);
	console = Console::init();
	Logger::log("Server started...");
	world = new World();
	instance = this;
}

Server::~Server()
{
}

void Server::kill()
{
	static bool killed = false;
	if (killed)
		exit(1);
	killed = true;
	Logger::log("Suiciding!!!");
	if (!instance)
	{
		exit(-1);
	}
	Logger::log("Closing viewer listener sockets...");
	if (instance->viewerListener)
	{
		delete instance->viewerListener;
		instance->viewerListener = 0;
	}
	Logger::log("Closing client listener sockets...");
	if (instance->clientListener)
	{
		delete instance->clientListener;
		instance->clientListener = 0;
	}
	if (instance->clients.count() > 0)
	{
		Logger::log("Closing client sockets...");
		QVectorIterator<ClientWorker*> it(instance->clients);
		while (it.hasNext())
		{
			ClientWorker *client = it.next();
			delete client;
		}
	}
	if (instance->viewers.count() > 0)
	{
		Logger::log("Closing viewer socket...");
		QVectorIterator<ViewerWorker*> it(instance->viewers);
		while (it.hasNext())
		{
			ViewerWorker *viewer = it.next();
			delete viewer;
		}
	}
	instance->console->close();
	exit(1);
}

void Server::setup()
{
	viewerListener = new ViewerListener(this);
	viewerListener->start();
	clientListener = new ClientListener(this);
	clientListener->start();
	world->init(this);
	world->startSimulation();
	world->run();
}

void Server::addViewer(ViewerProtocol *protocol)
{
	ViewerWorker* viewer = new ViewerWorker(this, protocol);
	viewer->start();
	viewers.append(viewer);
}

void Server::killViewer(ViewerWorker *worker)
{
	int index = viewers.indexOf(worker, 0);
	viewers.remove(index);
	worker->terminate();
	//delete worker;
}

void Server::addClient(ClientProtocol *protocol)
{
	ClientWorker *client = new ClientWorker(this, protocol);
	client->start();
	clients.append(client);
}

void Server::killClient(ClientWorker *worker)
{
	int index = clients.indexOf(worker, 0);
	clients.remove(index);
	worker->terminate();
	//delete worker;
}

Console * Server::getConsole()
{
	return instance->console;
}

QVariant Server::getSetting(const QString name, const QVariant defaultValue =
		QVariant())
{
	QString prefix("Robotsd/");
	return settings->value(prefix + name, defaultValue);
}
